package njust.csc.aeapi.utils

import com.google.zxing.*
import com.google.zxing.client.j2se.BufferedImageLuminanceSource
import com.google.zxing.client.j2se.MatrixToImageWriter
import com.google.zxing.common.BitMatrix
import com.google.zxing.common.HybridBinarizer
import com.google.zxing.qrcode.QRCodeWriter
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
import kotlin.io.path.Path
import com.google.zxing.Result
import io.github.oshai.kotlinlogging.KotlinLogging
import java.nio.file.Path
import kotlin.io.path.exists
private val logger = KotlinLogging.logger {}

/**
 * @Author ZhouHang
 * @Date 24/6/14 周五
 */

/**
 * 二维码生成类
 */
class QRCodeGenerator {
    /**
     * 二维码生成
     * @param data String 待编码的数据
     * @param filePath String 二维码图像保存绝对路径
     */
    fun generateQrCode(data: String, filePath: String) {
        generateQrCode(data, Path(filePath))
    }

    /**
     * 二维码生成
     * @param data String 待编码的数据
     * @param filePath Path 二维码图像保存绝对路径
     */
    fun generateQrCode(data: String, filePath: Path) {
        // 创建参数对象，设定纠错等级
        val hints: MutableMap<EncodeHintType, ErrorCorrectionLevel?> = java.util.HashMap<EncodeHintType, ErrorCorrectionLevel?>()
        hints[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.L

        // 创建二维码写入器，并生成BitMatrix
        val qrCodeWriter = QRCodeWriter()
        val bitMatrix: BitMatrix = qrCodeWriter.encode(data, BarcodeFormat.QR_CODE, 300, 300, hints)

        // 将BitMatrix转换为图片并输出到指定路径
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", filePath)
    }
}

class QRCodeDecoder {
    /**
     * 二维码解码
     * @param filePath String 待解码的二维码图像绝对路径
     * @return String 解码数据
     */
    fun decodeQrCode(filePath: String): String {
        return decodeQrCode(Path(filePath))
    }

    /**
     * 二维码解码
     * @param filePath Path 待解码的二维码图像绝对路径
     * @return String 解码数据
     */
    fun decodeQrCode(filePath: Path): String {
        if (!filePath.exists()) {
            logger.info { "二维码图片不存在: ${filePath.toAbsolutePath()}" }
            return ""
        }
        // 加载图片文件
        val image: BufferedImage = ImageIO.read(filePath.toFile())

        // 创建二值化图像
        val source = BufferedImageLuminanceSource(image)
        val binarizer = HybridBinarizer(source)
        val bitmap = BinaryBitmap(binarizer)

        // 创建多格式解码器并解码
        val multiFormatReader = MultiFormatReader()
        val result: Result
        try {
            result = multiFormatReader.decode(bitmap)
            return result.text
        } catch (e: NotFoundException) {
            throw RuntimeException("二维码未找到或无法解码")
        }
    }
}